#include "iic_basen32lib.h"

/**
 * @brief  Inserts a delay time.
 * @param count specifies the delay time length.
 */
void delay_us(uint32_t count)
{
    count=(count*4);
    for (; count > 0; count--)
    {
        __nop();
        __nop();
        __nop();
        __nop();
        __nop();
        __nop();
        __nop();
        __nop();
        __nop();
        
       
    }
}
void delay_ms(uint32_t count)
{
    for (; count > 0; count--)
   {
        delay_us(1006);
   }
}

/**
  * @brief SDA线输入模式配置
  * @param bus IIC总线控制器
  * @retval None
  */
static void SDA_Input_Mode(s_iic_bus_t* bus)
{
    GPIO_InitType GPIO_InitStructure ;
    GPIO_InitStruct(&GPIO_InitStructure);
	 

    GPIO_InitStructure.Pin = bus->IIC_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Input;
    GPIO_InitStructure.GPIO_Pull = GPIO_No_Pull;
    GPIO_InitPeripheral(bus->IIC_SDA_GPIO, &GPIO_InitStructure);
}
/**
  * @brief SDA线输出模式配置
  * @param bus IIC总线控制器
  * @retval None
  */
static void SDA_Output_Mode(s_iic_bus_t *bus)
{
	
    GPIO_InitType GPIO_InitStructure;
    GPIO_InitStruct(&GPIO_InitStructure);

    GPIO_InitStructure.Pin = bus->IIC_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pull = GPIO_No_Pull;
    GPIO_InitPeripheral(bus->IIC_SDA_GPIO, &GPIO_InitStructure);
}

/**
  * @brief SDA线输出一个位
  * @param bus IIC总线控制器 val 输出的数据 1/0
  * @retval None
  */
static void SDA_Output(s_iic_bus_t *bus, uint8_t val)
{
		if(val)GPIO_SetBits(bus->IIC_SDA_GPIO,bus->IIC_SDA_PIN);
		else GPIO_ResetBits(bus->IIC_SDA_GPIO,bus->IIC_SDA_PIN);
}

/**
  * @brief SCL线输出一个位
  * @param bus IIC总线控制器 val 输出的数据 1/0
  * @retval None
  */
static void SCL_Output(s_iic_bus_t *bus, uint8_t val)
{
	  if(val)GPIO_SetBits(bus->IIC_SCL_GPIO,bus->IIC_SCL_PIN);
		else GPIO_ResetBits(bus->IIC_SCL_GPIO,bus->IIC_SCL_PIN);
}

/**
  * @brief SDA输入一位
  * @param bus IIC总线控制器 
	* @return 读到的一位数据
  * @retval GPIO读入一位
  */
 uint8_t SDA_Input(s_iic_bus_t *bus)
{
	return GPIO_ReadInputDataBit(bus->IIC_SDA_GPIO,bus->IIC_SDA_PIN);
}
// _____
// SDA: |_____
// _______
// SCL:   |___
/**
  * @brief IIC起始信号
  * @param bus IIC总线控制器
  * @retval None
  */
void IICStart(s_iic_bus_t *bus)
{
	SDA_Output_Mode(bus);
	
	SDA_Output(bus,1);
	SCL_Output(bus,1);
	delay_us(4);
	
	SDA_Output(bus,0);
	delay_us(4);
	SCL_Output(bus,0);
	
}
//            _____
// SDA: _____|
//          _______
// SCL: ___|
/**
  * @brief IIC结束信号
  * @param bus IIC总线控制器
  * @retval None
  */
void IICStop(s_iic_bus_t *bus)
{
	SDA_Output_Mode(bus);
	SCL_Output(bus,0);
	SDA_Output(bus,0);
	delay_us(4);

	SCL_Output(bus,1);
	delay_us(4);
	SDA_Output(bus,1);
	delay_us(4);
}
// 应答___        非应答      __________       
// SDA:   |_______     SDA:
//         _____                  _____
// SCL:___|     |      SCL:   ___|     |
/**
  * @brief IIC主机等待从机应答
  * @param bus IIC总线控制器
  * @retval None
  */
uint8_t IICWaitAck(s_iic_bus_t *bus)
{
	uint8_t ucErrTime=0;
	SDA_Input_Mode(bus);
	
	
	SDA_Output(bus,1);
	delay_us(1);
	SCL_Output(bus,1);
	delay_us(1);
	
	while((SDA_Input(bus)==1))//应答超时
	{
			ucErrTime++;
		if(ucErrTime >=250)
		{
			IICStop(bus);
			return 1;
		}
	
	}
		SCL_Output(bus,0);
	
		return 0;
}
/**
  * @brief IIC发送应答信号（主机）
  * @param bus IIC总线控制器
  * @retval None
  */
void IICSendAck(s_iic_bus_t *bus)
{

	SCL_Output(bus,0);
	SDA_Output_Mode(bus);
	SDA_Output(bus,0);
	delay_us(2);
	
	SCL_Output(bus,1);
	delay_us(2);
	SCL_Output(bus,0);
	
}
/**
  * @brief IIC发送非应答信号（主机）
  * @param bus IIC总线控制器
  * @retval None
  */
void IICSendNotAck(s_iic_bus_t *bus)
{

	SCL_Output(bus,0);
	SDA_Output_Mode(bus);
	SDA_Output(bus,1);
	delay_us(2);
	SCL_Output(bus,1);
	delay_us(2);
	SCL_Output(bus,0);
}
/**
  * @brief IIC发送一个字节
  * @param byte 需要发送的字节
  * @retval None
  */
 void IICSendByte(s_iic_bus_t *bus,uint8_t cSendByte)
{
  uint8_t  i = 0;
	SDA_Output_Mode(bus);
	SCL_Output(bus,0);
	
	for(i=0;i<8;i++)
	{

		if((cSendByte&0x80)>>7)SDA_Output(bus,1);
		else SDA_Output(bus,0);
		
		cSendByte <<=1;
		delay_us(2);
		SCL_Output(bus,1);
		delay_us(2);
		SCL_Output(bus,0);
		delay_us(2);
	
	}
}
/**
  * @brief IIC接收一个字节
  * @param None 0 nack 1 ack
  * @retval 接收到的字节
  */
 uint8_t IICReceiveByte(s_iic_bus_t *bus, uint8_t ack)
{
		uint8_t i = 0;
    uint8_t cReceiveByte = 0;
    SDA_Input_Mode(bus);
	  for(i=0;i<8;i++)
		{
			SCL_Output(bus,0);
			delay_us(2);
			SCL_Output(bus,1);
			cReceiveByte <<=1;
			if(SDA_Input(bus))
			{
				cReceiveByte++;
			}
			delay_us(2);
		}
		if(!ack ) IICSendNotAck(bus);
		else IICSendAck(bus);
		return cReceiveByte;
}


void IICInit(s_iic_bus_t *bus)
{
   
	 GPIO_InitType GPIO_InitStructure ;   /*初始化GPIO结构体*/
	 GPIO_InitStruct(&GPIO_InitStructure);
	
	 GPIO_InitStructure.Pin            = bus->IIC_SCL_PIN ; 
	 GPIO_InitStructure.GPIO_Current   = GPIO_DC_4mA;
	 GPIO_InitStructure.GPIO_Pull      = GPIO_No_Pull;
	 GPIO_InitStructure.GPIO_Mode      =  GPIO_Mode_Out_PP;
	 GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;//以高速50M速率为例 翻转电平仅需20ns
	
	 GPIO_InitPeripheral(bus->IIC_SCL_GPIO, &GPIO_InitStructure);
	 GPIO_InitStructure.Pin            = bus->IIC_SDA_PIN ; 
	 GPIO_InitPeripheral(bus->IIC_SDA_GPIO, &GPIO_InitStructure);
	
	
	 GPIO_SetBits(bus->IIC_SDA_GPIO,bus->IIC_SDA_PIN);/*拉高总线*/
   GPIO_SetBits(bus->IIC_SCL_GPIO,bus->IIC_SCL_PIN);

}
